package cn.tedu.zx.court.adapter.impl;


import cn.tedu.zx.common.exception.ServiceException;
import cn.tedu.zx.common.restful.JsonPage;
import cn.tedu.zx.common.restful.ResponseCode;
import cn.tedu.zx.court.adapter.mapper.CourtMapper;
import cn.tedu.zx.court.service.CourtService;
import cn.tedu.zx.pojo.court.dto.CourtAddNewDto;
import cn.tedu.zx.pojo.court.dto.CourtUpdateDto;
import cn.tedu.zx.pojo.court.entity.Court;
import cn.tedu.zx.pojo.court.vo.CourtDetailsVo;
import cn.tedu.zx.pojo.court.vo.CourtGroupListVo;
import cn.tedu.zx.pojo.court.vo.CourtListVo;
import cn.tedu.zx.pojo.court.vo.CourtUserWatchListVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class CourtServiceImpl implements CourtService {
    private String message = null;

    private Court court = new Court();

    @Value("${zx.resource.base-dir}")
    private String baseDir;

    @Autowired
    private CourtMapper courtMapper;


    @Override
    public void addNew(CourtAddNewDto courtAddNewDto) {
        log.debug("往场地添加文件");

        //检查数据冲突情况
        checkConflict(courtAddNewDto.getName(), 0L);

        BeanUtils.copyProperties(courtAddNewDto, court);
        court.setCreated(LocalDateTime.now());
        court.setUpdated(LocalDateTime.now());
        log.trace("往数据库添加子项：{}", court);
        int insert = courtMapper.insert(court);

        //检查操作是否全部成功
        operateFailed(insert);
        log.trace("{}添加完成", court);
    }

    @Override
    public void deleteById(Long id) {
        log.debug("{}", id);

        //检查数据是否存在
        checkEmpty(id);

        //搜素本地图片文件并进行修改
        deleteImg(id);

        int delete = courtMapper.deleteById(id);

        //检查操作是否全部成功
        operateFailed(delete);
    }


    @Override
    public void updateById(CourtUpdateDto courtUpdateDto) {
        log.debug("{}", courtUpdateDto);

        //检查数据是否存在
        checkEmpty(courtUpdateDto.getId());

        //检查数据冲突情况
        checkConflict(courtUpdateDto.getName(), courtUpdateDto.getId());

        //搜素本地图片文件并进行修改
        deleteImg(courtUpdateDto.getId());

        BeanUtils.copyProperties(courtUpdateDto, court);
        court.setUpdated(LocalDateTime.now());
        log.trace("往数据库修改子项：{}", court);
        int updateById = courtMapper.updateById(court);

        //检查操作是否全部成功
        operateFailed(updateById);
        log.trace("{}修改完成", court);
    }

    @Override
    public CourtDetailsVo selectDetailsById(Long id) {
        log.debug("传入的id：{}", id);

        //检查数据是否存在
        CourtDetailsVo courtDetailsVO = courtMapper.selectDetailsById(id);
        log.debug("查到的数据：{}", courtDetailsVO);
        if (courtDetailsVO == null) {
            message = "查询失败，根据【id=" + id + "】查询的场地详情不存在";
            log.warn(message);
            throw new ServiceException(ResponseCode.NOT_FOUND, message);
        }
        return courtDetailsVO;
    }

    @Override
    public JsonPage<CourtListVo> list(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<CourtListVo> list = courtMapper.list();
        PageInfo pageInfo = new PageInfo(list);
        return JsonPage.restPage(pageInfo);
    }

    @Override
    public void updateIsEnableBuId(Long id, Integer isEnable) {
        //检查数据是否存在
        checkEmpty(id);

        Court court = new Court();
        court.setId(id);
        court.setIsEnable(isEnable);
        courtMapper.updateById(court);
    }

    @Override
    public List<CourtGroupListVo> listByCategoryId(Long id) {
        List<CourtGroupListVo> courtGroupListVos = courtMapper.listByCategoryId(id);
        if (courtGroupListVos == null) {
            message = "操作失败，数据不存在";
            log.warn(message);
            throw new ServiceException(ResponseCode.NOT_FOUND, message);
        }
        return courtGroupListVos;
    }

    /**
     * 通过id检查数据是否存在
     * @param id
     */

    private void checkEmpty(Long id) {
        QueryWrapper<Court> albumWrapper = new QueryWrapper();
        albumWrapper.eq("id", id);
        int countById = courtMapper.selectCount(albumWrapper);
        if (countById == 0) {
            message = "操作失败，数据不存在";
            log.warn(message);
            throw new ServiceException(ResponseCode.NOT_FOUND, message);
        }
    }

    /**
     * 文件操作是否与预测一致
     * @param operatedRows
     */
    private void operateFailed(Integer operatedRows) {
        if (operatedRows < 1) {
            String message = "服务器忙,请稍后再试";
            throw new ServiceException(ResponseCode.INTERNAL_SERVER_ERROR, message);
        }
    }

    /**
     * 通过名称字段及id检查内容是否冲突
     * @param name
     * @param id
     */
    private void checkConflict(String name, Long id) {
        QueryWrapper<Court> categoryWrapper = new QueryWrapper();
        categoryWrapper.eq("name", name).ne("id", id);
        int countByName = courtMapper.selectCount(categoryWrapper);
        log.debug("查询数据{}", countByName);
        if (countByName > 0) {
            message = "操作失败，场地名已占用";
            log.warn(message);
            throw new ServiceException(ResponseCode.CONFLICT, message);
        }
    }

    /**
     * 通过id查询相关路径并删除本地图片文件
     * @param id
     */
    private void deleteImg(Long id){

        String oldUrl = courtMapper.selectDetailsById(id).getUrl();

        //url使用端口拼接
        String substring = oldUrl.substring(oldUrl.indexOf("/picture"));

        log.trace("获取路径：{}",substring);
        String url = baseDir + substring;
        //url不加端口拼接

//        String url = baseDir+"/"+oldUrl;

        File file = new File(url);

        if (file.exists()) {
            file.delete();
        }
    }

    @Override
    public List<CourtUserWatchListVo> UserWatchList() {
        List<CourtUserWatchListVo> list = courtMapper.UserWatchList();
        return list;
    }
}
